package com.eatme.web.sys.workflow.activiti.controller;

import com.eatme.web.sys.workflow.activiti.service.ActivitiService;
import com.eatme.web.common.QueryCondition;
import com.eatme.web.common.vo.AppResponse;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

@Controller
@RequestMapping("process")
public class ProcessDefinitionController {
    private static final Logger LOG = LoggerFactory.getLogger(ProcessDefinitionController.class);

    @Autowired
    private RepositoryService repositoryService;


    @Autowired
    ActivitiService activitiServiceImpl;

    @Autowired
    private ProcessRuntime processRuntime;

    //添加流程定义通过上传bpmn
    @PostMapping("definition/uploadStreamAndDeployment")
    @ResponseBody
    public AppResponse uploadStreamAndDeployment(@RequestParam("file") MultipartFile file
//            , @RequestParam("deploymentName") String deploymentName
    ) throws IOException {
        // 获取上传文件名
        String resourceName = file.getOriginalFilename();
        //
        String extension = FilenameUtils.getExtension(resourceName);
        // 获取文件字节流对象
        InputStream fileInputStream = file.getInputStream();
        Deployment deployment = null;
        if (extension.equals("zip")) {
            ZipInputStream zipInputStream = new ZipInputStream(fileInputStream);
            deployment = repositoryService.createDeployment()// 初始化部署
                    .addZipInputStream(zipInputStream)
//                    .name(deploymentName)
                    .deploy();
        } else {
            deployment = repositoryService.createDeployment()
                    .addInputStream(resourceName, fileInputStream)
//                    .name(deploymentName)
                    .deploy();
        }
        LOG.debug(deployment.toString());
        Map<String, Object> map = new HashMap<>();
        map.put("deploymentId", deployment.getId());
        return AppResponse.ok().data(map);
    }

    //添加流程定义通过在线提交bpmn的xml
    @PostMapping("definition/uploadStringAndDeployment")
    @ResponseBody
    public AppResponse uploadStringAndDeployment(@RequestBody  Map<String,Object> map) {
        String text = (String) map.get("text");
        Deployment deployment = null;
        deployment = repositoryService.createDeployment()// 初始化部署
                .addString("createWithBPMNJS.bpmn", text)
                //.name(deploymentName)
                .deploy();
        return AppResponse.ok();
    }


    //获取流程定义列表
    @PostMapping("definition/list")
    @ResponseBody
    public AppResponse definitionList(@RequestBody QueryCondition<Map<String,Object>> queryCondition) {
        Integer pageSize = queryCondition.getPage().getPageSize();
        Integer pageIndex = queryCondition.getPage().getPageIndex();
        List<Map<String,Object>> listMap = new ArrayList<>();
        List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().listPage(pageIndex,pageSize);
        for(ProcessDefinition processDefinition: list) {
            HashMap<String,Object> hashMap = new HashMap<>();
            hashMap.put("name",processDefinition.getName());
            hashMap.put("key",processDefinition.getKey());
            hashMap.put("resourceName",processDefinition.getResourceName());
            hashMap.put("deploymentId",processDefinition.getDeploymentId());
            hashMap.put("version",processDefinition.getVersion());
            listMap.add(hashMap);
        }
        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("total",repositoryService.createDeploymentQuery().count());
        if (!list.isEmpty()){
            resultMap.put("list",listMap);
        }
        return AppResponse.ok().data(resultMap);
    }

    //获取流程定义xml
    @RequestMapping(value = "definition/detail/{id}", produces = {"text/xml"}, method = RequestMethod.GET)
    public void getDefinitionXML(HttpServletResponse response,@PathVariable(value = "id") String deploymentId) throws IOException {
//        String deploymentId = (String) map.get("deploymentId");
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult();
        InputStream inputStream = repositoryService.getResourceAsStream(deploymentId, processDefinition.getResourceName());
        int count = inputStream.available();
        byte[] bytes = new byte[count];
        response.setContentType(MediaType.TEXT_XML_VALUE);
        response.setCharacterEncoding("utf-8");
        OutputStream outputStream = response.getOutputStream();
        while (inputStream.read(bytes) != -1) {
            outputStream.write(bytes);
        }
        inputStream.close();
    }
    //获取流程部署列表
    @PostMapping("deployment/list")
    @ResponseBody
    public AppResponse deploymentList(@RequestBody QueryCondition<Map<String,Object>> queryCondition) {
        Integer pageSize = queryCondition.getPage().getPageSize();
        Integer pageIndex = queryCondition.getPage().getCurrentPage();
        List<Map<String,Object>> listMap = new ArrayList<>();
        List<Deployment> list = repositoryService.createDeploymentQuery().listPage((pageIndex-1)*pageSize,pageSize);
        for(Deployment deployment: list) {
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
            HashMap<String,Object> hashMap = new HashMap<>();
            hashMap.put("id",deployment.getId());
            hashMap.put("name",deployment.getName());
            hashMap.put("deploymentTime",deployment.getDeploymentTime());
            hashMap.put("version",deployment.getVersion());
            hashMap.put("key",deployment.getKey());
            hashMap.put("processDefinitionName",processDefinition.getName());
            hashMap.put("processDefinitionKey",processDefinition.getKey());
            hashMap.put("resourceName",processDefinition.getResourceName());
            hashMap.put("processDefinitionVersion",processDefinition.getVersion());
            listMap.add(hashMap);
        }
        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("total",repositoryService.createDeploymentQuery().count());
        if (!list.isEmpty()){
            resultMap.put("list",listMap);
        }
        return AppResponse.ok().data(resultMap);
    }
    //删除流程定义
    @PostMapping("definition/delete")
    @ResponseBody
    public AppResponse deleteDefinition(@RequestBody Map<String,Object> map) {
        String deploymentId = (String) map.get("deploymentId");
        String definitionId = (String) map.get("definitionId");
        //删除数据
//        int result = activitiServiceImpl.delete(definitionId);
        repositoryService.deleteDeployment(deploymentId,true);
        return AppResponse.ok();
    }

}
